import fs from "fs-extra";
import path from "path";
import { toolchain } from "../../toolchain.js";
import { BaseTask, TaskResult } from "./BastTask.js";
import { sendBuildFailureAlert, sendRobotMsg } from "../../tools/alert.js";
import { Hudson } from "../../tools/hudson.js";
import { SVNInfo } from "./SVNSaveTask.js";

export interface SVNSumary {
    diffJsonNames?: string[]
    jsonDiff?: string
    addNewCsharps?: string[]
}

export class SVNOperationTask extends BaseTask<SVNSumary> {
    async run(): Promise<TaskResult<SVNSumary>> {
        // 更新svrinfo
        //await toolchain.svnClient.cleanup(true, toolchain.params.hostCfg.svrinfo);
        //await toolchain.svnClient.revert(toolchain.params.hostCfg.svrinfo);
        //await toolchain.svnClient.update(toolchain.params.hostCfg.svrinfo);

        const data: SVNSumary = await this.cleanProj(toolchain.params.workSpacePath, toolchain.params.svn.urlMap.code[toolchain.params.projectType]);

        return { success: true, errorCode: 0, data };
    }

    protected async cleanProj(workspacePath: string, responsitory: string): Promise<SVNSumary> {
        console.time('SVN更新耗时');
        const out: SVNSumary = {
            diffJsonNames: [],
            jsonDiff: '', 
            addNewCsharps: []
        };

        console.log('=============================clean project===============================');
        // 有些项目svn可能没有project这一级，比如一些临时拉的测试项目
        // 先检测是否有project
        let svnContainsProject = true;
        try {
            await toolchain.svnClient.info(responsitory + '/project', '--show-item', 'kind');
        } catch(e) {
            if (e instanceof Error) {
                if (e.message.includes('svn: E200009: Could not display info for all targets because some targets don\'t exist')) {
                    svnContainsProject = false;
                }
            }
        }
        console.log('client svn contains project node? ' + (svnContainsProject ? 'Y' : 'N'));
        let rootpath = workspacePath;
        if (svnContainsProject && rootpath.endsWith('project')) {
            rootpath = path.join(rootpath, '..');
        }
        
        console.log('project root:' + rootpath); 
        if(fs.existsSync(workspacePath)) {
            await toolchain.svnClient.cleanup(false, rootpath);
            await toolchain.svnClient.cleanup(false, workspacePath);
            await toolchain.svnClient.revert(rootpath);

            // // 生成json配置的diff文件
            // const diffFile = path.join(workspacePath, `../.build/json@${Hudson.getBuildNumber()}.diff`);
            // if (fs.existsSync(diffFile)) {
            //     await fs.unlink(diffFile);
            // }
            // let jsonRoot: string = '';
            // if (toolchain.option.engine != 'laya') {
            //     jsonRoot = path.join(workspacePath, 'Assets/AssetSources/data');
            // }
            // if (jsonRoot && fs.existsSync(jsonRoot)) {
            //     const svnInfoFile = path.join(workspacePath, `../.build/svnInfo.json`);
            //     let jsonRevision = 0;
            //     if (fs.existsSync(svnInfoFile)) {
            //         const svnInfo: SVNInfo = await fs.readJson(svnInfoFile);
            //         jsonRevision = svnInfo.json;
            //     } else {
            //         jsonRevision = await toolchain.svnClient.getRevision(jsonRoot);
            //     }
                
            //     console.log('json revision:', jsonRevision);
            //     console.time('json_diff_time');
            //     const diffOut:string = null!;//await toolchain.svnClient.cmd('diff', [jsonRoot, '-r', `${jsonRevision}:HEAD`], undefined, true);
            //     console.timeEnd('json_diff_time');

            //     console.time('diff_save_time');
            //     if (diffOut) {
            //         await fs.ensureDir(path.dirname(diffFile));
            //         await fs.writeFile(diffFile, diffOut, 'utf-8');
            //         // 解析diff文件
            //         const mchs = diffOut.matchAll(/Index: .*\b(\w+)\b\.json/g);
            //         for (const mch of mchs) {
            //             out.diffJsonNames!.push(mch[1]);
            //         }
            //         out.jsonDiff = diffFile;
            //     }
            //     console.timeEnd('diff_save_time');
            // }

            let triedTimes = 0, isConflict = false;
            while (triedTimes < 2) {
                console.time('svn_update_time');
                const updateOut = await toolchain.svnClient.update(rootpath);
                console.timeEnd('svn_update_time');
                // 检查更新了哪些json，是否有新增C#脚本
                const lines = updateOut.split(/\r?\n/);
                for (const line of lines) {
                    const mch = line.match(/^A    (.+\.cs)$/);
                    if (mch != null) {
                        out.addNewCsharps!.push(mch[1]);
                    } else {
                        const jmch = line.match(/^U    .+\\data\\(.+\.json)$/);
                        if (jmch!= null) {
                            out.diffJsonNames!.push(jmch[1]);
                        }
                    }
                }
                if (updateOut.includes('Summary of conflicts')) {
                    // svn冲突，revert后继续
                    isConflict = true;
                    console.time('svn_revert_time');
                    await toolchain.svnClient.revert(rootpath);
                    console.timeEnd('svn_revert_time');
                } else {
                    isConflict = false;
                    break;
                }
                triedTimes++;
            }
            if (isConflict) {
                sendBuildFailureAlert('SVN冲突');
                process.exit(1);
            }

            if (out.diffJsonNames?.length) {
                toolchain.buildMessages.push(`本次构建更新了<font color='red'>${out.diffJsonNames.length}</font>个配置：${out.diffJsonNames.join(', ')}`);
            } else {
                toolchain.buildMessages.push("本次构建更新了<font color='red'>0</font>个配置");
            }
        } else{
            fs.mkdirSync(rootpath, { recursive: true });
            await toolchain.svnClient.checkout(responsitory, rootpath);
        }
        console.log('addNewCsharps count: ' + (out.addNewCsharps?.length || 0));
        console.timeEnd('SVN更新耗时');

        return out;
    }
}
